package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Sctmwlsensor;
import com.example.onlinemonitoring.model.Zxdblqsensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.Sctmwlhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Mxcwsensor;
import com.example.onlinemonitoring.serviceImpl.SctmwlsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*这里beanName需要和数据库Appdevice中的simple对应并加上Com,不对应请自行修改
    例:simple:dlhl
    @Service("dlhlCom")
*/
@Service("sctmwlCom")
@Scope("prototype")
public class SctmwlCom extends CommPortManager {
     private int cmdtype = 0;
        @Autowired
        private SctmwlsensorServiceImpl sctmwlsensorServiceImpl;

        @Override
        public void receiveData(String str) {
            try {
                str = str.toUpperCase();
                setText(str);
                String addrstr = str.substring(0, 2);
                Integer addr = parseHex4(addrstr) ;

                Integer startIndex = 6;//数据起始位置
                if (str.length()<10)
                return;
                reSend[addrindex] = 0;
                
                if(str.length()>15){
                    float LastTemper = 0;
                    float LastV = 0;
                    int count = 0;
                    setText("设备返回数据： 站点号：" + ad.getStationid() +  " 设备地址：" + addr);
                    String blqtip1;
                    
                    blqtip1 = str.substring(2, 4);

                    Sctmwlsensor wlcwsensor =  new Sctmwlsensor();
                    wlcwsensor.setStationid(ad.getStationid());
                    wlcwsensor.setDeviceaddr(addr);
                    wlcwsensor.setDevicegroup(ad.getDevicegroup());
                    MyResult<Sctmwlsensor> res = sctmwlsensorServiceImpl.getList(wlcwsensor);
                    startIndex = 6;//数据起始位置
                        
                //条件判断自己写
                     if(cmdtype == 0)
                     {

                        for (int i = 0; i < 120; i++) {

                        LastTemper = parseHex88(str.substring(startIndex, startIndex+=4))/10;
                        setText( " 节点:"+(i + 1)+" 温度：" + LastTemper + " ");
                        
                        Sctmwlsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                            return;
                        }
                        if(record.getInuse()==0)
                        continue;

                        wlcwsensor.setPointaddr(record.getPointaddr());
                        wlcwsensor.setLastatemper(LastTemper);
                        wlcwsensor.setLastabv(record.getLastabv());
                        wlcwsensor.setLastdatatime(new Date());
                        AddAndUpdate(record,wlcwsensor);
                        }
                         cmdtype = 2;
                        if(res.getCount()>120)
                            cmdtype = 1;

                     }
                    else 
                     if(cmdtype == 1)
                     {

                        for (int i = 120; i < res.getCount(); i++) {

                        LastTemper = parseHex88(str.substring(startIndex, startIndex+=4))/10;
                        setText( " 节点:"+(i + 1)+" 温度：" + LastTemper + " ");
                        
                        Sctmwlsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                            return;
                        }
                        if(record.getInuse()==0)
                        continue;

                        wlcwsensor.setPointaddr(record.getPointaddr());
                        wlcwsensor.setLastatemper(LastTemper);
                        wlcwsensor.setLastabv(record.getLastabv());
                        wlcwsensor.setLastdatatime(new Date());
                        AddAndUpdate(record,wlcwsensor);
                        }
                        cmdtype = 2;
                     }
                    else 
                    if(cmdtype == 2)
                    {
                        for (int i = 0; i < 120; i++) {

                        LastV = parseHex88(str.substring(startIndex, startIndex+=4))/1;
                        setText( " 节点:"+(i + 1)+"电压：" + LastV + "mV ");
                    //查询对象
                        Sctmwlsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                            return;
                        }
                        if(record.getInuse()==0)
                        continue;

                        wlcwsensor.setPointaddr(record.getPointaddr());
                        wlcwsensor.setLastabv(LastV);
                        wlcwsensor.setLastcommunicationstatus(0);
                        wlcwsensor.setLastdatatime(new Date());
                        if ( sctmwlsensorServiceImpl.Update(wlcwsensor, false) == 0) {
                            setText("更新实时数据失败，请检查数据库连接");
                        }
                        }
                        cmdtype = 0;
                        if(res.getCount()>120)
                            cmdtype = 3;
                            else{
                                addrindex++;                                
                            }

                    }
                    else 
                    if(cmdtype == 3)
                    {
                        for (int i = 120; i < res.getCount(); i++) {

                        LastV = parseHex88(str.substring(startIndex, startIndex+=4))/1;
                        setText( " 节点:"+(i + 1)+"电压：" + LastV + "mV ");
                    //查询对象
                        Sctmwlsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                            return;
                        }
                        if(record.getInuse()==0)
                        continue;

                        wlcwsensor.setPointaddr(record.getPointaddr());
                        wlcwsensor.setLastabv(LastV);
                        wlcwsensor.setLastcommunicationstatus(0);
                        wlcwsensor.setLastdatatime(new Date());
                        if ( sctmwlsensorServiceImpl.Update(wlcwsensor, false) == 0) {
                            setText("更新实时数据失败，请检查数据库连接");
                        }
                        }
                        cmdtype = 0;
                        addrindex++;
                    }
                }else{
                    setText("从设备返回的数据有误！请检查串口！");
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }

        @Transactional
        private void AddAndUpdate(Sctmwlsensor record,Sctmwlsensor wlcwsensor) {
                if (record.getAtemperalarmvalue() == null ||
                record.getAtemperalarmrelievevalue() == null ||
                record.getAtemperwarnvalue() == null ||
                record.getAtemperwarnrelievevalue() == null ||
                record.getBvalarmvalue() == null ||
                record.getBvalarmrelievevalue() == null ||
                record.getBvwarnvalue() == null ||
                record.getBvwarnrelievevalue() == null
        ) {
            setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
            return;
        }
        
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            //报警逻辑
            List<Integer> array = new ArrayList<>();
            wlcwsensor.setLastatemperalarmstatus(
                GetAlarmStatus(isnull(wlcwsensor.getLastatemper()), isnull(record.getAtemperalarmvalue()),
                        isnull(record.getAtemperalarmrelievevalue()), isnull(record.getAtemperwarnvalue()),
                        isnull(record.getAtemperwarnrelievevalue()),
                        isnull(wlcwsensor.getLastatemperalarmstatus()), true, "节点温度",record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(),record.getPointaddr()));
            alarmMessage += GetAlarmMessage(wlcwsensor.getLastatemperalarmstatus(), "节点温度");
            array.add(wlcwsensor.getLastatemperalarmstatus());
            wlcwsensor.setLastabvalarmstatus(
                GetAlarmStatus(isnull(wlcwsensor.getLastabv()), isnull(record.getBvalarmvalue()),
                        isnull(record.getBvalarmrelievevalue()), isnull(record.getBvwarnvalue()),
                        isnull(record.getBvwarnrelievevalue()),
                        isnull(wlcwsensor.getLastabvalarmstatus()), true, "节点电压",record.getDevicegroup(),  record.getDeviceaddr(),
                        record.getPointname(),record.getPointaddr()));
            alarmMessage += GetAlarmMessage(wlcwsensor.getLastabvalarmstatus(), "节点电压");
            array.add(wlcwsensor.getLastabvalarmstatus());
             alarmLevel = HexUtil.MAX(array);
            wlcwsensor.setLastalarmlevel(alarmLevel);
            wlcwsensor.setLastalarmmessage(alarmMessage);
            wlcwsensor.setLastcommunicationstatus(0);
            wlcwsensor.setLastdatatime(new Date());
            wlcwsensor.setLasthisdatatime(addHistory(record));
            if ( sctmwlsensorServiceImpl.Update(wlcwsensor, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Sctmwlsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Sctmwlsensor sensor) {
            Sctmwlhistory his = new Sctmwlhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setStationid(sensor.getStationid());
            his.setPointaddr(sensor.getPointaddr());
            //需要添加自己定义的属性
            his.setAtemper(sensor.getLastatemper());
            his.setAbv(sensor.getLastabv());
            his.setAtemperalarmstatus(sensor.getLastatemperalarmstatus());
            his.setAbvalarmstatus(sensor.getLastabvalarmstatus());
            sctmwlsensorServiceImpl.Add(his);
        }


        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";
            issend.put(Thread.currentThread().getId(), true);
            String cstr = "";
            String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                if(cmdtype==0)
                {                    
                    cstr = String.format("%s0305DD0078", String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                }
                else if(cmdtype==1)
                {                    
                    cstr = String.format("%s0306550078", String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                }
                else if(cmdtype==2)
                {
                    cstr = String.format("%s0309C50078", String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);

                }
                else if(cmdtype==3)
                {
                    cstr = String.format("%s030A3D0078", String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);

                }
                try {
                    Send(cstr);
                } catch (Exception EX) {
                     setText(EX.toString());
                }
                setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                sctmwlsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                reSend[addrindex] = 0;
                addrindex++;
                }
                Thread.sleep(timersp);
            }
        }
        public static float parseHex88(String num) {
            int ret = Integer.parseInt(num, 16);
            if (num.length() == 2) {
                return ret;
            } else if (num.length() == 4) {
                ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
                return ret;
            } else {
                throw new NumberFormatException("Wrong length: " + num.length() + ", must be 4.");
            }
        }
        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
